package cc.lj.internal.coupons.domain.ticket.service.impl.useTicketRule;

import cc.lj.internal.api.ordershare.dto.OrderOnlineAPIDTO;
import cc.lj.internal.core.exception.ServiceException;
import cc.lj.internal.coupons.domain.ticket.model.vo.TicketBatchDO;
import cc.lj.internal.coupons.domain.ticket.repository.IUseTicketCheckCacheRepository;
import cc.lj.internal.coupons.infrastructure.excepion.CoupousExceptionEnum;
import cc.lj.internal.coupons.interfaces.dto.command.UseTicketCheckCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 用券过程中，在判断满减规则时，判断当前用的券是否是阶梯的第一张券，工具类
 * @author liangxifeng
 * @date 2023/6/29 14:48
 */

@Component("findFirstStepUtil")
@Slf4j
public class FindFirstStepUtil {
    //用券验证 redis 缓存仓储接口
    @Resource(name = "usetTicketCheckCacheRedisRepositoryImpl")
    private IUseTicketCheckCacheRepository cacheRepository;

    /**
     * 断该券是否是每个阶梯中的第一张券
     * @param batchDO
     * @param pactNum 合同号
     * @param uuId 唯一识别码UUID
     * @param addOrDelete 新增或删除券操作，1:新增，2:删除券
     * @return true:是，false:不是
     */
    public boolean isStepFirstTicket(TicketBatchDO batchDO, String pactNum,String uuId,Integer addOrDelete) {
        if(uuId == null) throw new ServiceException(CoupousExceptionEnum.USE_TICKET_CHECK_UUID_IS_NULL);
        //1.从redis中读取券批次使用数量 <券批次主键，已用券数量>
        Map<Integer,Integer> usedBatchNumHash = cacheRepository.getUseBatch(pactNum,uuId);
        log.info("已用券批次数量redis中的数据<券批次主键=>券使用张数>="+usedBatchNumHash);
        Integer usedTicketNum = 0; //已用券数量
        //如果从redis中能够取到券批次 对用 已使用数量, 则将 已用券数量 赋值
        if(usedBatchNumHash != null ) {
            Integer a = usedBatchNumHash.get(batchDO.getBatchId());
            if (usedBatchNumHash.get(batchDO.getBatchId()) != null) {
                System.out.println(usedBatchNumHash.get(batchDO.getBatchId()));
                if (usedBatchNumHash.get(batchDO.getBatchId()) > 0) {
                    usedTicketNum = usedBatchNumHash.get(batchDO.getBatchId());
                }
            }
        }
        //为了计算整数，这里将已用券数量 和 券可用张数 转换为 BigDecimal 类型
        BigDecimal usedTicketNumBigDecimal = new BigDecimal(usedTicketNum);
        BigDecimal canUseTicketNumBigDecimal = new BigDecimal(batchDO.getConditionNumber());
        log.info("券批次主键="+batchDO.getBatchId()+",已用券张数="+ (addOrDelete==1 ? usedTicketNum : (usedTicketNum-1))+", 可用券张数="+canUseTicketNumBigDecimal.intValue());

        //这里如果是删除券操作，则已用券张数需要-1
        if (addOrDelete == 2) usedTicketNumBigDecimal = usedTicketNumBigDecimal.subtract(new BigDecimal(1));
        // 如果 已用券张数 / 可用券张数 = 整数 （每个阶梯的第一次用券）(注意：这里的除法是保留4位小时，做四舍五入)
        BigDecimal divideNum = usedTicketNumBigDecimal.divide(canUseTicketNumBigDecimal,4,BigDecimal.ROUND_HALF_UP);
        if( isInteger( divideNum ) ) {
            log.info("已用券张数 / 可用券张数="+divideNum+",结果是整数，也就等于该阶段的第一张券");
            return true;
        }else {
            log.info("已用券张数 / 可用券张数="+divideNum+",结果不是整数，也就不是该阶段的第一张券");
            return false;
        }
    }

    /**
     * 判断指定 BigDecimal 是否为整数
     * @param number
     * @return true:是整数，false:不是整数
     */
    private boolean isInteger(BigDecimal number) {
        if(number != null ) {
            if (new BigDecimal(number.intValue()).compareTo(number)==0){
                //整数
                return true;
            }else {
                //小数
                return false;
            }
        }
        return false;
    }
}
